package com.wld.vertx;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Pattern;

import com.alibaba.fastjson.JSONObject;
import com.wld.vertx.config.VertxConfig;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.ServerWebSocket;
import io.vertx.core.http.WebSocketFrame;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.bridge.PermittedOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;

public class ProducerHttpServerVerticle extends AbstractVerticle {

    private Map<String, ServerWebSocket> connectionMap = new HashMap<>(16);

    private final String REG = "(/tp-data-push-service/\\d+/.*/websocket)|(/tp-data-push-service/websocket)";


    public void start() {
        createEventBridgeAndRegisterHandlers();
    }

    private void createEventBridgeAndRegisterHandlers() {
        HttpServer httpServer = vertx.createHttpServer();
        Router router = Router.router(vertx);
        SockJSHandler sockJSHandler = SockJSHandler.create(vertx);
        router.route().handler(CorsHandler.create("*"));

        PermittedOptions allAllowed = new PermittedOptions().setAddressRegex(".*");
        router.route(VertxConfig.THIRD_PARTY_ROUTE_URI).handler(sockJSHandler.bridge(new BridgeOptions()
                .addInboundPermitted(allAllowed)
                .addOutboundPermitted(allAllowed), be -> {
            be.complete(true);
        }));

        httpServer.websocketHandler(serverWebSocket -> {
            String id = serverWebSocket.binaryHandlerID();
            System.out.println("id: " + id);
            //健康的全数据
           
            if (Pattern.matches(REG, serverWebSocket.path())) {
                if (!checkID(id)) {
                    connectionMap.put(id, serverWebSocket);
                }
                System.out.println("发送全数据");
                SendAllHealthData();
                serverWebSocket.handler(buff -> {
                    JsonObject receiveData = buff.toJsonObject();
                    if (receiveData.getString("type").equals("register")) {
                        String address = receiveData.getString("address");
                        vertx.eventBus().consumer(address, message -> {
                            JsonObject sendBody = new JsonObject().put("body", message.body());
                            if (checkID(id)) {
                                System.out.println("sendBody: " + sendBody);
                                connectionMap.get(id).writeFrame(WebSocketFrame.textFrame(sendBody.encode(), true));
                            }
                        });
                    }
                });
            }

            serverWebSocket.closeHandler(close -> {
                connectionMap.remove(id);
            });
        });

        httpServer.requestHandler(router::accept).listen(VertxConfig.PORT, ar -> {
            if (ar.succeeded()) {
                System.out.println("HttpServerVerticle is listening at port: " + VertxConfig.PORT);
            } else {
                System.out.println("HttpServerVerticle failed to start, cause: " + ar.cause());
                vertx.close();
                System.exit(-1);
            }
        });

        publish();
    }
    
    public static String RECOVERY = "RECOVERY";
    public static String NEW = "NEW";
    
    
    // 检查当前ID是否已经存在与map中	
    private boolean checkID(String id) {
        return connectionMap.containsKey(id);
    }
    
    ///发送健康的全数据数据
    private void SendAllHealthData()
    {
    	long timerID = vertx.setTimer(1000, id -> {
    		vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 1)
	                .put("status", "健康")
	                .put("code", "JK"));
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 119)
	                .put("status", "告警")
	                .put("code", "JK"));
	    	
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 121)
	                .put("status", "故障")
	                .put("code", "JK"));
	    	
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 413)
	                .put("status", "健康")
	                .put("code", "JK"));
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 87)
	                .put("status", "告警")
	                .put("code", "JK"));
	    	
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 95)
	                .put("status", "故障")
	                .put("code", "JK"));
	    	
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 99)
	                .put("status", "健康")
	                .put("code", "JK"));
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 411)
	                .put("status", "故障")
	                .put("code", "JK"));
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 91)
	                .put("status", "健康")
	                .put("code", "JK"));
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 97)
	                .put("status", "故障")
	                .put("code", "JK"));
	    	
	    	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 409)
	                .put("status", "健康")
	                .put("code", "JK"));
	    	
    		});
    
    }
  
    
    //定时器的推送
    private void publish() {
    	
    	//健康状态
        vertx.setPeriodic(3000, id -> {
        	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 1)
	                .put("status", "隐患")
	                .put("code", "JK"));
        	
        	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 119)
	                .put("status", "健康")
	                .put("code", "JK"));
        	
        	vertx.eventBus().publish(VertxConfig.HEALTH_STATUS_ADDRESS, new JsonObject()
	                .put("id", 121)
	                .put("status", "告警")
	                .put("code", "JK"));
	    
        });
        
       
        //实时地址
        vertx.setPeriodic(5000, id -> {
            vertx.eventBus().publish(VertxConfig.REAL_TIME_DATA_ADDRESS, new JsonObject()
                    .put("id", 1)
                    .put("time", new Date().getTime())
                    .put("data", new JsonObject(JSONObject.toJSONString(getRealdata()))));
            
            
            vertx.eventBus().publish(VertxConfig.REAL_TIME_DATA_ADDRESS, new JsonObject()
                    .put("id", 119)
                    .put("time", new Date().getTime())
                    .put("data", new JsonObject(JSONObject.toJSONString(getRealdata()))));
            
            
            vertx.eventBus().publish(VertxConfig.REAL_TIME_DATA_ADDRESS, new JsonObject()
                    .put("id", 121)
                    .put("time", new Date().getTime())
                    .put("data", new JsonObject(JSONObject.toJSONString(getRealdata()))));
            
            
        });
        
        
        
        //订阅检测量
        vertx.setPeriodic(5000, id -> {
            vertx.eventBus().publish(VertxConfig.EQUIPMENT_MODELESTATUS, new JsonObject()
                    .put("id", 1)
                    .put("time", new Date().getTime())
                    .put("data", new JsonObject(JSONObject.toJSONString(getZTdata()))));
            
            
            vertx.eventBus().publish(VertxConfig.EQUIPMENT_MODELESTATUS, new JsonObject()
                    .put("id", 119)
                    .put("time", new Date().getTime())
                    .put("data", new JsonObject(JSONObject.toJSONString(getZTdata()))));
            
            
            vertx.eventBus().publish(VertxConfig.EQUIPMENT_MODELESTATUS, new JsonObject()
                    .put("id", 121)
                    .put("time", new Date().getTime())
                    .put("data", new JsonObject(JSONObject.toJSONString(getZTdata()))));
            
            
        });
        
        
        
        //设备报警
        ///{
        //"event": "RECOVERY",                 // 两个类型：  NEW("新增"), RECOVERY("恢复");
       // "data": {
       //  "id": 1621,           //报警ID
        // "equipment": {       //报警设备
        //  "id": 263,           //设备ID
        //  "name": "室内温湿度传感器-二次设备间东侧",   //设备名称
        //  "number": "SNWSD4"         // 设备编号
       //  },
        // "itemName": "温度",      // 报警监测量名称
       //  "itemCode": "WD",      // 报警监测量编码    
        // "status": "CB",       // 报警级别
       //  "startTime": "2022-04-24 15:15:33",  // 报警开始时间
       //  "endTime": "2022-04-24 15:46:18"   // 报警结束时间
        //}
       //}
        vertx.setPeriodic(10000, id -> {
            vertx.eventBus().publish(VertxConfig.ALARM_ADDRESS, new JsonObject()
                    .put("event", RECOVERY)
                    .put("itemCode", "JBFD")
                    .put("itemName", "局部放电")
                    .put("status", "status")
                    .put("startTime", "startTime")
                    .put("endTime", "endTime")
                    .put("data", new JsonObject(JSONObject.toJSONString(GetAlarmData(1)))));
            
            
            vertx.eventBus().publish(VertxConfig.ALARM_ADDRESS, new JsonObject()
                    .put("event", RECOVERY)
                    .put("itemCode", "JBFD")
                    .put("itemName", "局部放电")
                    .put("status", "status")
                    .put("startTime", "startTime")
                    .put("endTime", "endTime")
                    .put("data", new JsonObject(JSONObject.toJSONString(GetAlarmData(119)))));
            
            
            vertx.eventBus().publish(VertxConfig.ALARM_ADDRESS, new JsonObject()
                    .put("event", RECOVERY)
                    .put("itemCode", "JBFD")
                    .put("itemName", "局部放电")
                    .put("status", "status")
                    .put("startTime", "startTime")
                    .put("endTime", "endTime")
                    .put("data", new JsonObject(JSONObject.toJSONString(GetAlarmData(121)))));
            
            
        });
        
        
        vertx.setPeriodic(15000, id -> {
            vertx.eventBus().publish(VertxConfig.ALARM_ADDRESS, new JsonObject()
                    .put("event", NEW)
                    .put("itemCode", "JBFD")
                    .put("itemName", "局部放电")
                    .put("status", "status")
                    .put("startTime", "startTime")
                    .put("endTime", "endTime")
                    .put("data", new JsonObject(JSONObject.toJSONString(GetAlarmData(1)))));
            
            
            vertx.eventBus().publish(VertxConfig.ALARM_ADDRESS, new JsonObject()
                    .put("event", NEW)
                    .put("itemCode", "JBFD")
                    .put("itemName", "局部放电")
                    .put("status", "status")
                    .put("startTime", "startTime")
                    .put("endTime", "endTime")
                    .put("data", new JsonObject(JSONObject.toJSONString(GetAlarmData(119)))));
            
            
            vertx.eventBus().publish(VertxConfig.ALARM_ADDRESS, new JsonObject()
                    .put("event", NEW)
                    .put("itemCode", "JBFD")
                    .put("itemName", "局部放电")
                    .put("status", "status")
                    .put("startTime", "startTime")
                    .put("endTime", "endTime")
                    .put("data", new JsonObject(JSONObject.toJSONString(GetAlarmData(121)))));
            
            
        });
        
       
        
        
    }

    private Map<String, Map> getRealdata() {
    	Random random = new Random();
        Map<String, Map> map = new HashMap<>();
        Map data = new HashMap();
        data.put("code", "GYCDL_A");
        data.put("name", "高压侧电流A");
        data.put("value", random.nextInt(100));
        data.put("recordDate", LocalDateTime.now());
        map.put("GYCDL_A", data);
        return map;
    }
    
    private Map<String, Map> getZTdata() {
    	Random random = new Random();
        Map<String, Map> map = new HashMap<>();
        Map data = new HashMap();
        data.put("code", "YW_ZT");
        data.put("name", "油温状态");
        data.put("value", random.nextInt(100));
        data.put("recordDate", LocalDateTime.now());
        map.put("YW_ZT", data);
        return map;
    }
    
   private Map<String, Map> GetAlarmData(int id)
   {
	   Map<String, Map> map = new HashMap<>();
       Map data = new HashMap();
       data.put("id",id);
       Map equipment = new HashMap();
       equipment.put("id", 263);
       equipment.put("name", "室内温湿度传感器-二次设备间东侧");
       equipment.put("number", "SNWSD4");
       data.put("equipment", equipment);
       map.put("data", data);
       return map;
   }
}